﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using NLog;
using ShkSimulation.core.dao.input.loader;
using ShkSimulation.core.dao.output;
using ShkSimulation.core.dao.output.result;
using ShkSimulation.core.template;
using ShkSimulation.core.template.model;
using ShkSimulation.desktop.setting;
using ShkSimulation.desktop.util;
using ShkSimulation.carsharing.impl.elements;

namespace ShkSimulation.desktop.component.parallel {

	public partial class MultiSimulationForm : Form {

		public List<Network> networks = new List<Network>();


		public MultiSimulationForm() {
			InitializeComponent();
			this.ResultTextBox.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\result-data";
		}

		private void StartRunButton_Click(object sender, EventArgs e) {
			IReadOnlyList<InputConfig> configs = this.parallelConfigPanel1.ParallelConfigs;
			if (configs.Count == 0) {
				MessageBox.Show(@"没有配置哈！", @"提示");
				return;
			}
			if (!Directory.Exists(ResultTextBox.Text)) {
				MessageBox.Show(@"请先配置结果保存路径！", @"提示");
				return;
			}
			if (RunWorker.IsBusy) {
				MessageBox.Show(@"正在运行请等待！", @"提示");
				return;
			}
			RunWorker.RunWorkerAsync();
		}

        private void ResultTextBox_DoubleClick(object sender, EventArgs e) {
			string folderPath = FileUtil.OpenFolder(FolderDialog, @"选择结果保存目录");
			if (!string.IsNullOrEmpty(folderPath)) {
				ResultTextBox.Text = folderPath;
			}
        }

        private void RunWorker_DoWork(object sender, DoWorkEventArgs e) {
	        this.Invoke(new Action(() => {
		        this.InfoStatusLabel.Text = @"正在运行";
	        }));
	        LogManager.DisableLogging();
	        IReadOnlyList<InputConfig> configs = this.parallelConfigPanel1.ParallelConfigs;
	        List<BackgroundWorker> workers = new List<BackgroundWorker>(configs.Count);
	        TimeSpan days = ConfigManager.UserRunConfig.仿真时长;
	        DateTime start = ConfigManager.UserRunConfig.仿真开始时刻;
	        bool realTime = ConfigManager.UserRunConfig.真实时间;
	        Console.WriteLine(ConfigManager.UserRunConfig);
	        for (int i = 0; i < configs.Count; i++) {
		        BackgroundWorker worker = new BackgroundWorker();
		        int index = i;
		        InputConfig config = configs[index];
		        string key = config.GetConfigValue<string>(ParallelConfigPanel.CONFIG_UNIQUE_KEY);
		        worker.DoWork += (_, _) => {
			        NetworkResultHolder resultHolder = new NetworkResultHolder();
			        NetworkInputData inputData = new NetworkEnvironment(config, new ExcelResourceLoader());
			        Network network = QueueNetwork.GenerateNetwork(inputData, resultHolder, null, null, (index * -1));
			        network.Init(start);
			        if (realTime) {
				        network.ContinousRun(days, days);
			        } else {
				        network.RunWithTerminate(days, days);
			        }
			        Result result = resultHolder.GetCurrentResult((index * -1).ToString());
			        ResultShower shower = new ExcelResultShower(ResultTextBox.Text + "/result-" + key + ".xlsx");
			        Console.WriteLine(@"Save Result:{0}", key);
			        shower.Show(result);
		        };
		        worker.RunWorkerAsync();
		        workers.Add(worker);
	        }
	        Stopwatch stopwatch = Stopwatch.StartNew();
	        long timeSpan = TimeSpan.FromSeconds(10).Ticks;
	        while (true) {
		        bool allFinish = true;
		        foreach (var worker in workers) {
			        if (worker.IsBusy) {
				        allFinish = false;
				        Thread.Sleep(100);
				        break;
			        }
		        }
		        this.RunTimeStatusLabel.Text = stopwatch.Elapsed.ToString();
		        if (allFinish) {
			        break;
		        }
		        if (stopwatch.ElapsedTicks % timeSpan == 0) {
			        Console.WriteLine(@"+10S");
		        }
	        }
	        LogManager.EnableLogging();
	        this.Invoke(new Action(() => {
		        this.InfoStatusLabel.Text = @"运行完成";
	        }));
        }
    }

}